/*
 * JSmexCardService is a abstract class which defines methods for all CardServices which extends the class.
 * These methods are needed by the ExplorerFunctions class.
 *
 * Created on 24. Oktober 2006, 16:07
 *
 *  This file is part of JSmex.
 *
 *  JSmex is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  JSmex is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Foobar; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

package jsmex.cardservice;

import jsmex.LogTracer;
import jsmex.function.SmartCardFile;
import opencard.core.service.CardService;
import opencard.core.service.CardServiceScheduler;
import opencard.core.service.CardServiceException;
import opencard.core.service.SmartCard;
import opencard.core.terminal.CardID;
import opencard.core.terminal.CardTerminalException;
import opencard.core.terminal.CommandAPDU;
import opencard.core.terminal.ResponseAPDU;
import opencard.core.util.HexString;

/**
 *
 * @author Tobias Senger
 */
public abstract class JSmexCardService extends CardService{
    
    private CardID cardID;
    protected LogTracer lt;
    
    /**
     * Creates a new instance of JSmexCardService
     */
    public JSmexCardService() {
        super();
    }
    
    /**
     * Set a LogTracer instance for this class.
     * @param lt A LogTracer instance
     */
    public void setLogTracer(LogTracer lt) {
        this.lt = lt;
    }
    
    protected void initialize(CardServiceScheduler sched, SmartCard card, boolean blocking) throws CardServiceException {
        super.initialize(sched, card, blocking);
        cardID = card.getCardID();
    }
    
    /**
     * Gets the ATR from the inserted card.
     * @return The ATR as String.
     */
    protected String getATR() {
        StringBuffer sb = new StringBuffer();
        byte [] atr = cardID.getATR();
        sb.append(HexString.hexify(atr) );
        
        lt.info("called method getATR() returns ATR: "+sb.toString(),this);
        return sb.toString();
    }
    
    /**
     * This method allocate a cardchannel, send the commandAPDU to the card and release the cardchannel.
     * @param commandAPDU The CommandAPDU
     * @return The ResponseAPDU
     */
    public ResponseAPDU sendCommandAPDU(CommandAPDU commandAPDU) throws CardTerminalException{
        ResponseAPDU rsp;
        
        try {
            lt.info("allocate CardChannel",this);
            allocateCardChannel();
            rsp = getCardChannel().sendCommandAPDU(commandAPDU);
            lt.info("called method sendCommandAPDU(commandAPDU: "+HexString.hexify(commandAPDU.getBytes())+ "). returns: "+HexString.hexify(rsp.data())+" SW: "+HexString.hexify(rsp.sw1())+" "+HexString.hexify(rsp.sw2()),this);
        }
        
        finally {
            lt.info("release CardChannel",this);
            releaseCardChannel();
        }
        return rsp;
    }
    
    public abstract SmartCardFile[] getFileList(SmartCardFile scfile);
    
    public abstract ResponseAPDU selectEF(byte[] fid) throws Exception;
    
    public abstract ResponseAPDU selectDF(byte[] fid) throws Exception;
    
    public abstract ResponseAPDU readBinary(byte oh, byte ol, byte length) throws Exception;
    
    public abstract ResponseAPDU readRecord(byte recno, int length) throws Exception;
    
    public abstract ResponseAPDU updateBinary(byte oh, byte ol, byte[] data) throws Exception;
    
    public abstract ResponseAPDU updateRecord(byte recno, byte[] data) throws Exception;
    
    public abstract boolean selectMF() throws Exception;
    
    public abstract ResponseAPDU verifyCHV(byte chvindication, String chv);
    
    public abstract boolean chvIsVerified(int chvindicator);
    
    public abstract SmartCardFile getSmartCardFile(String fidString);
    
}
